from django.views.generic import View
from .forms import AuthForm, RoleForm, PermissionForm, LogForm, UserForm
from .models import UserModel, RoleModel, PermissionModel, UserRoleModel, RolePermissionModel, UserLogModel
from config_app.models import ProjectModel
from Alpha.settings import user_log
from utils.messages import Form_Invalid, Json_Response
from utils.decorators import permission_verify
from utils.paginate import paginate
from utils.token import encode_token
from utils.fmt import datetime_str
from copy import deepcopy
import datetime, time


class AuthView(View):

    def _create_token(self, AuthInstance: UserModel, permission_ids: list, token_key):
        '''
         生效时间即刻开始
         失效时间为24h
        '''
        now = time.time()
        payload = {
            'user_info': {
                'usr_id': AuthInstance.id,
                'usr_name': AuthInstance.usr_name,
                'usr_phone': AuthInstance.usr_phone,
                'usr_mail': AuthInstance.usr_mail,
                'last_login': str(AuthInstance.last_login),
                'permissions': permission_ids,
            },
            'effect_timestamp': now,
            'expire_timestamp': now + 24 * 3600,
            'token_key': token_key
        }
        token = encode_token(payload)

        return token

    def _get_permission(self, user_id):
        q_permission = []
        for role_obj in RoleModel.objects.filter(to_user__id=user_id):
            for obj in PermissionModel.objects.filter(to_role__id=role_obj.id):
                q_permission.append({
                    'id': obj.id,
                    'app': obj.app,
                    'name': obj.name,
                    'operate': obj.operate,
                })
        # 去重
        details = []  # 权限详情
        ids = []  # 权限id
        for i in q_permission:
            if i['id'] not in ids:
                details.append(i)
                ids.append(i['id'])

        return details, ids

    def _get_project(self, user_id):
        result = []
        qs = ProjectModel.objects.filter(to_user__id=user_id).values_list(
            'id', 'proj_name', 'proj_desc', named=True)
        for obj in qs:
            result.append({
                'proj_id': obj.id,
                'proj_name': obj.proj_name,
                'proj_desc': obj.proj_desc
            })
        return result

    # 登录
    def login(self, request):
        form = AuthForm.Login(request)
        if form.is_valid():
            status, instance, message = UserModel.objects.login(**form.cleaned_data)
            if status:  # 登陆成功后，查询权限，生成token
                if not instance.is_super:
                    details, ids = self._get_permission(instance.id)
                else:
                    details, ids = ['*'], ['*']
                token = self._create_token(instance, ids, instance.token_key)
                result = {
                    'name': instance.usr_name,
                    'permissions': ids,
                    'intro': '超级管理员' if instance.is_super else '普通用户',
                    'projects': self._get_project(instance.id),
                    'token': token
                }
                LogView.record_log(instance.id, 0)
                response = Json_Response(msg=message, data=result)
            else:
                response = Json_Response(code=201, err_msg=message)
            return response
        else:
            return Form_Invalid(form)

    # 登出
    def logout(self, request):
        id = request.USER_INFO['usr_id']
        UserModel.objects.logout(id)
        LogView.record_log(id, 1)
        return Json_Response(msg='注销成功')

    # 修改密码
    def change_password(self, request):
        form = AuthForm.ChangePassword(request)
        if form.is_valid():
            user_id, new_pwd = request.USER_INFO['usr_id'], form.cleaned_data['new_pwd']
            UserModel.objects.set_pwd(user_id, new_pwd)
            LogView.record_log(user_id, 2)
            return Json_Response(msg='密码修改成功')
        else:
            return Form_Invalid(form)


class UserView(View):

    # 新增用户
    @permission_verify(10002)
    def insert(self, request):
        pass

    # 删除用户
    @permission_verify(10002)
    def delete(self, request):
        pass

    # 查询用户列表
    @permission_verify(10001)
    def user_list(self, request):
        form = UserForm.UserList(request)
        if form.is_valid():
            data = form.cleaned_data
            result = []
            user_qs = UserModel.objects.all()
            total = user_qs.count()

            for user in paginate(user_qs, data['page'], data['page_size']).values(
                    'id', 'usr_name', 'usr_phone', 'usr_mail', 'is_valid', 'is_super', 'last_login'):
                result.append({
                    'id': user['id'],
                    'name': user['usr_name'],
                    'phone': user['usr_phone'],
                    'mail': user['usr_mail'],
                    'is_valid': user['is_valid'],
                    'is_super': user['is_super'],
                    'last_login': datetime_str(user['last_login']) if user['last_login'] else None
                })
            return Json_Response(msg='查询成功', data={
                'total': total,
                'page': data['page'],
                'page_size': data['page_size'],
                'result': result
            })
        else:
            return Form_Invalid(form)

    # 修改用户信息
    @permission_verify(10002)
    def update(self, request):
        form = UserForm.Update(request)
        if form.is_valid():
            data = form.cleaned_data
            qs = UserModel.objects.filter(id=data['id'])
            qs.update(**data)
            for obj in qs:
                obj.save()
            return Json_Response(msg='更新成功')
        else:
            return Form_Invalid(form)


class RoleView(View):

    # 创建角色
    @permission_verify(10004)
    def create_role(self, request):
        form = RoleForm.RoleCreate(request)
        if form.is_valid():
            if not RoleModel.objects.filter(role_name=form.cleaned_data['role_name']):
                obj = RoleModel.objects.create(**form.cleaned_data)
                LogView.record_log(request, 11, obj)
                return Json_Response(msg='创建成功')
            else:
                return Json_Response(code=201, err_msg='创建失败,角色已存在')
        else:
            return Form_Invalid(form)

    # 删除角色
    @permission_verify(10004)
    def delete_role(self, request):
        form = RoleForm.RoleDelete(request)
        if form.is_valid():
            for obj in RoleModel.objects.filter(id=form.cleaned_data['role_id']):
                obj_copy = deepcopy(obj)
                obj.delete()
                LogView.record_log(request, 12, obj_copy)
                return Json_Response(msg='删除成功')
            else:
                return Json_Response(code=201, msg='已删除')
        else:
            return Form_Invalid(form)

    # 获取角色列表
    @permission_verify(10003)
    def role_list(self, request):
        form = RoleForm.RoleList(request)
        if form.is_valid():
            result = []
            data = form.cleaned_data
            page, page_size = data['page'], data['page_size']
            total = RoleModel.objects.all().count()
            role_qs = paginate(RoleModel.objects.filter(), page, page_size)
            for role in role_qs.values('id', 'role_name', 'role_desc', 'create_time'):
                result.append({
                    'id': role['id'],
                    'name': role['role_name'],
                    'desc': role['role_desc'],
                    'create_time': datetime_str(role['create_time'])
                })
            return Json_Response(msg='查询成功', data={
                'page': page,
                'page_size': page_size,
                'total': total,
                'result': result
            })
        else:
            return Form_Invalid(form)

    # 获取用户当前角色
    @permission_verify(10001)
    def get_role(self, request):
        form = RoleForm.RoleGet(request)
        if form.is_valid():
            result = []
            data = form.cleaned_data
            current_role_qs = RoleModel.objects.filter(to_user__id=form.cleaned_data['user_id'])
            role_qs = RoleModel.objects.all()
            for obj in role_qs:
                if obj in current_role_qs:
                    obj.register = True
                else:
                    obj.register = False

            for obj in role_qs:
                result.append({
                    'role_id': obj.id,
                    'role_name': obj.role_name,
                    'role_desc': obj.role_desc,
                    'register': obj.register,
                })

            return Json_Response(msg='查询成功', data={'user_id': data['user_id'], 'result': result})
        else:
            return Form_Invalid(form)

    # 更新用户当前角色
    @permission_verify(10002)
    def update_role_user(self, request):
        form = RoleForm.UpdateRoleUser(request)
        if form.is_valid():
            data = form.cleaned_data
            user_id, role_ids = data['user_id'], data['role_ids']

            # 先删除所有对应关系
            UserRoleModel.objects.filter(usr__id=user_id).delete()

            # 建立新对应关系
            for role in role_ids:
                UserRoleModel.objects.create(**{
                    'usr': UserModel.objects.get(id=user_id),
                    'role': RoleModel.objects.get(id=role),
                })
            return Json_Response(msg='更新成功')
        else:
            return Form_Invalid(form)


class PermissionView(View):

    # 获取角色当前权限
    @permission_verify(10003)
    def get_permission(self, request):
        form = PermissionForm.PermissionGet(request)
        if form.is_valid():
            result = []
            role_id = form.cleaned_data['role_id']
            current_permission_qs = PermissionModel.objects.filter(to_role__id=role_id)
            permission_qs = PermissionModel.objects.all()

            for obj in permission_qs:
                obj.register = True if obj in current_permission_qs else False

            for obj in permission_qs:
                result.append({
                    'permission_id': obj.id,
                    'permission_name': obj.name,
                    'permission_operate': obj.operate,
                    'permission_app': obj.app,
                    'register': obj.register
                })
            return Json_Response(msg='查询成功', data={'role_id': role_id, 'result': result})
        else:
            return Form_Invalid(form)

    # 更新角色当前权限
    @permission_verify(10004)
    def update_permission_role(self, request):
        form = PermissionForm.UpdatePermissionRole(request)
        if form.is_valid():
            data = form.cleaned_data
            role_id, permission_ids = data['role_id'], data['permission_ids']

            # 先删除所有对应关系
            RolePermissionModel.objects.filter(role__id=role_id).delete()

            # 建立新对应关系
            for p_id in permission_ids:
                RolePermissionModel.objects.create(**{
                    'role': RoleModel.objects.get(id=role_id),
                    'permission': PermissionModel.objects.get(id=p_id)
                })
            return Json_Response(msg='更新成功')
        else:
            return Form_Invalid(form)


class LogView(View):

    @staticmethod
    def record_log(request, action: int, target_obj=None):
        if user_log:
            try:
                usr_id = request.USER_INFO['usr_id']
            except AttributeError as e:
                usr_id = str(request)
            target_name, target_id = None, None
            if target_obj:
                target_name, target_id = target_obj.verbose_name, target_obj.id
            if UserModel.objects.filter(id=usr_id):
                UserLogModel.objects.create(**{
                    'action': action,
                    'target_name': target_name,
                    'target_id': target_id,
                    'user_by': UserModel.objects.get(id=usr_id)
                })

    @permission_verify(10005)
    def log_list(self, request):
        form = LogForm.LogList(request)
        if form.is_valid():
            result = []
            params = form.cleaned_data
            page, page_size = params['page'], params['page_size']
            log_qs = UserLogModel.objects.filter()
            count = log_qs.count()
            for obj in paginate(log_qs, page, page_size).values_list(
                    'id', 'action', 'target_name', 'target_id', 'time', 'user_by__usr_name', named=True):
                result.append({
                    'id': obj.id,
                    'action': {
                        'type': obj.action,
                        'value': UserLogModel.Action().output(obj.action)
                    },
                    'target_name': obj.target_name,
                    'target_id': obj.target_id,
                    'time': datetime_str(obj.time),
                    'user_by': obj.user_by__usr_name,
                })

            return Json_Response(
                msg='查询成功',
                data={
                    'page': page,
                    'page_size': page_size,
                    'count': count,
                    'result': result
                }
            )
        else:
            return Form_Invalid(form)
